import service
import GameWorld
import re
from catma import catmaDB

class attributeSvc(service.Service):
    __guid__ = 'svc.attributeSvc'
    __notifyevents__ = ['OnSessionChanged']

    def GetDB(self):
        raise NotImplementedError("attributeSvc doesn't implement GetDB()")



    def SetOnAttributeChanged(self):
        raise NotImplementedError("attributeSvc doesn't implement SetOnAttributeChanged()")



    def Run(self, *etc):
        service.Service.Run(self, *etc)
        self.attributeTable = GameWorld.AttributeTable()
        self.attributeCache = GameWorld.AttributeCache()
        self.attributeNameDict = {}
        self.catmaDataInitialized = False
        self.SetOnAttributeChanged()



    def OnSessionChanged(self, isRemote, sess, change):
        if ((not self.catmaDataInitialized) and (('userid' in change) and (change['userid'][0] is None))):
            self.catmaDataInitialized = True
            self.SetCatmaData(self.GetDB())



    def SetCatmaData(self, cDB):
        attributeTypes = cDB.GetTypeNamesOfClass('BatmaAttribute')
        self.attributeNameDict = {}
        for attributeTypeName in attributeTypes:
            attributeType = cDB.GetType(attributeTypeName)
            attributeID = attributeType.GetTypeID()
            self.attributeNameDict[attributeTypeName] = attributeID


        def ParseVariableNames(varString):
            if not varString:
                return 
            else:

                def GetAttributeSubstr(name):
                    str = name.group(0).strip('{}')
                    return ('getAttribute(%d, entID_hi, entID_lo)' % self.attributeNameDict.get(str, -1))


                regEx = '({.*?})'
                return re.sub(regEx, GetAttributeSubstr, varString, flags=re.IGNORECASE)


        for (attributeTypeName, attributeID,) in self.attributeNameDict.iteritems():
            try:
                attributeType = cDB.GetType(attributeTypeName)
                defaultValue = ParseVariableNames(attributeType.GetValue('defaultValue'))
                minValue = ParseVariableNames(attributeType.GetValue('minValue', None))
                maxValue = ParseVariableNames(attributeType.GetValue('maxValue', None))
                directlyModifiable = attributeType.GetValue('modifiable', False)
            except catmaDB.CatmaDBError, e:
                self.LogError(('AttributeSvc: CatmaDB error: %s' % e))
                continue
            self.attributeTable.AddAttributeFromPython(attributeID, defaultValue, minValue, maxValue)

        self.attributeTable.EvaluateAttributeDependencies()



    def GetAttributeNameToIDDict(self):
        return self.attributeNameDict



    def GetAttributeIDFromName(self, attributeName):
        if (self.attributeNameDict is None):
            return 
        else:
            attributeID = self.attributeNameDict.get(attributeName, None)
            return attributeID



    def GetAttributeFromEntity(self, attributeName, entid):
        attributeID = self.GetAttributeIDFromName(attributeName)
        if (attributeID is None):
            return 
        else:
            attributeValue = self.attributeCache.GetAttributeValueFromEntity(attributeID, entid)
            changePerSecond = self.attributeCache.GetAttributeChangeFromEntity(attributeID, entid)
            attributeMinValue = self.attributeCache.GetAttributeMinFromEntity(attributeID, entid)
            attributeMaxValue = self.attributeCache.GetAttributeMaxFromEntity(attributeID, entid)
            return [attributeValue,
             changePerSecond,
             attributeMinValue,
             attributeMaxValue]



    def GetAttributeValueFromEntity(self, attributeName, entid):
        attributeID = self.GetAttributeIDFromName(attributeName)
        if (attributeID is None):
            return 
        else:
            attributeValue = self.attributeCache.GetAttributeValueFromEntity(attributeID, entid)
            change = self.attributeCache.GetAttributeChangeFromEntity(attributeID, entid)
            return attributeValue



    def GetAttributeMinFromEntity(self, attributeName, entid):
        attributeID = self.GetAttributeIDFromName(attributeName)
        if (attributeID is None):
            return 
        else:
            attributeValue = self.attributeCache.GetAttributeMinFromEntity(attributeID, entid)
            return attributeValue



    def GetAttributeMaxFromEntity(self, attributeName, entid):
        attributeID = self.GetAttributeIDFromName(attributeName)
        if (attributeID is None):
            return 
        else:
            attributeValue = self.attributeCache.GetAttributeMaxFromEntity(attributeID, entid)
            return attributeValue




